home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1996 #15
/
Monster Media Number 15 (Monster Media)(July 1996).ISO
/
prog_c
/
cuj0696.zip
/
DWYER.ZIP
/
LIB
/
STIRLING.C
< prev
Wrap
C/C++ Source or Header
|
1995-12-01
|
5KB
|
228 lines
/* ============ */
/* stirling.c */
/* ============ */
#include <defcodes.h>
#include <math.h>
#include <mconf.h>
/* ------------------- */
/* FUNCTION PROTOTYPES */
/* ------------------- */
# undef F
# if defined(__STDC__) || defined(__PROTO__)
# define F( P ) P
# else
# define F( P ) ()
# endif
/* INDENT OFF */
extern double BinCoef F((double, double));
extern LDBL Stirling1 F((double, double));
extern LDBL Stirling2 F((double, double));
# undef F
/* INDENT ON */
#define MAX_ELEMS 100 /* Max Recursion List */
#define MAXNUM 1.701411834604692317316873e38; /* 2**127 */
/* ==================================================================== */
/* Stirling1 - Returns Stirling Number of the First Kind for S(n,m) */
/* ==================================================================== */
LDBL
Stirling1(double n, double m)
{
LDBL RetVal;
/* ---------------------------------------------------------------- */
/* The expressions used are from Handbook of Mathmetical Functions, */
/* ed. by M. Abramowitz and I. A. Stegun, U.S. Government Printing */
/* Office, 1964, Paragraph 24.1.3 and Table 24.3. */
/* ---------------------------------------------------------------- */
/* -------------------------------------------------------- */
/* S(n, m) = S(n-1,m-1) + (n-1) * S(n-1, m), n >= m >= 1 */
/* S(n, n) = 1 */
/* S(n, n-1) = [n*(n-1)]/2 */
/* S(n, 0) = 0 */
/* S(n, 1) = (n-1)! */
/* -------------------------------------------------------- */
if (m < 0 || n < 0 || m > n || n-m > MAX_ELEMS)
{
char Cause[32] = "Stirling1(): ";
strcat(Cause,
(m < 0) ? "(m < 0)" :
(n < 0) ? "(n < 0)" :
(m > n) ? "(m > n)" : "(n-m > 100)");
mtherr(Cause, DOMAIN);
RetVal = MAXNUM;
}
else if (m == n)
{
RetVal = 1;
}
else if (m == (n-1))
{
RetVal = (m*n)/2;
}
else if (m == 0)
{
RetVal = 0;
}
else if (m == 1)
{
RetVal = (n < 2) ? 1 : fac((int)n-1);
}
else
{
LDBL List[MAX_ELEMS], *P, Val;
int k;
/* ------------------------------- */
/* Set up recursion run for m = 1 */
/* (these are factorials (k-1)! ). */
/* ------------------------------- */
P = List;
*P = 1;
for (k = 2; k <= n - m; ++k)
{
Val = k * (*P++);
*P = Val;
}
/* -------------------------- */
/* Recurse runs from 2 to m. */
/* There are (n-m-1) elements */
/* per run. */
/* -------------------------- */
for (k = 2; k <= m; ++k)
{
int j;
LDBL Mult;
P = List;
/* ------------------------- */
/* First element is k(k+1)/2 */
/* ------------------------- */
*P = (k * (k+1)) >> 1;
Mult = k + 1;
for (j = 2; j <= n-m; ++j)
{
Val = (Mult++) * *P++;
*P += Val;
}
}
RetVal = *P;
}
return (RetVal);
}
/* ==================================================================== */
/* Stirling2 - Returns Stirling Number of the Second Kind for S(m,n) */
/* ==================================================================== */
LDBL
Stirling2(double n, double m)
{
long double RetVal;
/* ---------------------------------------------------------------- */
/* The expressions used are from Handbook of Mathmetical Functions, */
/* ed. by M. Abramowitz and I. A. Stegun, U.S. Government Printing */
/* Office, 1964, Paragraph 24.1.4 and Table 24.4. */
/* ---------------------------------------------------------------- */
/* -------------------------------------------------------- */
/* S(n, m) = S(n-1,m-1) + m * S(n-1, m), n >= m >= 1 */
/* S(n, n) = 1 */
/* S(n, n-1) = [n*(n-1)]/2 */
/* S(n, 0) = 0 */
/* S(n, 1) = 1 */
/* S(n, 2) = 2^n - 1 */
/* -------------------------------------------------------- */
if (m < 0 || n < 0 || m > n || n-m > MAX_ELEMS)
{
char Cause[32] = "Stirling2(): ";
strcat(Cause,
(m < 0) ? "(m < 0)" :
(n < 0) ? "(n < 0)" :
(m > n) ? "(m > n)" : "(n-m > 100)");
mtherr(Cause, DOMAIN);
RetVal = MAXNUM;
}
else if (m == n)
{
RetVal = 1;
}
else if (m == (n-1))
{
RetVal = (m*n)/2;
}
else if (m == 0)
{
RetVal = 0;
}
else if (m == 1)
{
RetVal = 1;
}
else if (m == 2)
{
RetVal = ldexp(0.5, (int)(n)) - 1;
}
else
{
LDBL List[MAX_ELEMS], *P, Val;
int k;
/* ------------------------------- */
/* Set up recursion run for m = 1 */
/* (these are Pk = 2^(k+1) - 1 ). */
/* ------------------------------- */
P = List;
for (k = 1; k <= n - m; ++k)
{
*P++ = ldexp(2., k) - 1;
}
/* -------------------------- */
/* Recurse runs from 3 to m. */
/* There are (n-m-1) elements */
/* per run. */
/* -------------------------- */
for (k = 3; k <= m; ++k)
{
int j;
LDBL Mult;
P = List;
/* ------------------------- */
/* First element is k(k+1)/2 */
/* ------------------------- */
*P = (k * (k+1)) >> 1;
Mult = k;
for (j = 2; j <= n-m; ++j)
{
Val = Mult * *P++;
*P += Val;
}
}
RetVal = *P;
}
return (RetVal);
}